home *** CD-ROM | disk | FTP | other *** search
/ Clickx 63 / Clickx 63.iso / software / multimedia / mirov204 / Miro_Installer.exe / xulrunner / chrome / toolkit.jar / content / global / viewSourceUtils.js < prev    next >
Encoding:
JavaScript  |  2007-09-17  |  9.4 KB  |  237 lines

  1. //@line 37 "/e/xr19rel/WINNT_5.2_Depend/mozilla/toolkit/components/viewsource/content/viewSourceUtils.js"
  2.  
  3. /*
  4.  * To keep the global namespace safe, don't define global variables and 
  5.  * functions in this file.
  6.  *
  7.  * This file requires contentAreaUtils.js
  8. */
  9.  
  10. var gViewSourceUtils = {
  11.  
  12.   mnsIWebBrowserPersist: Components.interfaces.nsIWebBrowserPersist,
  13.   mnsIWebProgress: Components.interfaces.nsIWebProgress,
  14.   mnsIWebPageDescriptor: Components.interfaces.nsIWebPageDescriptor,
  15.  
  16.   // Opens the interval view source viewer
  17.   openInInternalViewer: function(aURL, aPageDescriptor, aDocument)
  18.   {
  19.     // try to open a view-source window while inheriting the charset (if any)
  20.     var charset = null;
  21.     var isForcedCharset = false;
  22.     if (aDocument) {
  23.       charset = "charset=" + aDocument.characterSet;
  24.       try { 
  25.         isForcedCharset =
  26.           aDocument.defaultView
  27.                    .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  28.                    .getInterface(Components.interfaces.nsIDOMWindowUtils)
  29.                    .docCharsetIsForced;
  30.       } catch (ex) {
  31.       }
  32.     }
  33.     openDialog("chrome://global/content/viewSource.xul",
  34.                "_blank",
  35.                "all,dialog=no",
  36.                aURL, charset, aPageDescriptor, 0, isForcedCharset);
  37.   },
  38.  
  39.   // aCallBack is a function accepting two arguments - result (true=success) and a data object
  40.   // It defaults to openInInternalViewer if undefined.
  41.   openInExternalEditor: function(aURL, aPageDescriptor, aDocument, aCallBack)
  42.   {
  43.     var data = {url: aURL, pageDescriptor: aPageDescriptor, doc: aDocument};
  44.  
  45.     try {
  46.       var editor = this.getExternalViewSourceEditor();    
  47.       if (!editor) {
  48.         this.handleCallBack(aCallBack, false, data);
  49.         return;
  50.       }
  51.  
  52.       // make a uri
  53.       var ios = Components.classes["@mozilla.org/network/io-service;1"]
  54.                           .getService(Components.interfaces.nsIIOService);
  55.       var charset = aDocument ? aDocument.characterSet : null;
  56.       var uri = ios.newURI(aURL, charset, null);
  57.       data.uri = uri;
  58.  
  59.       var path;
  60.       var contentType = aDocument ? aDocument.contentType : null;
  61.       if (uri.scheme == "file") {    
  62.         // it's a local file; we can open it directly
  63.         path = uri.QueryInterface(Components.interfaces.nsIFileURL).file.path;
  64.         editor.run(false, [path], 1);
  65.         this.handleCallBack(aCallBack, true, data);
  66.       } else {
  67.         // set up the progress listener with what we know so far
  68.         this.viewSourceProgressListener.editor = editor;
  69.         this.viewSourceProgressListener.callBack = aCallBack;
  70.         this.viewSourceProgressListener.data = data;      
  71.         if (!aPageDescriptor) {
  72.           // without a page descriptor, loadPage has no chance of working. download the file.
  73.           var file = this.getTemporaryFile(uri, aDocument, contentType);
  74.           this.viewSourceProgressListener.file = file;
  75.  
  76.           var webBrowserPersist = Components
  77.                                   .classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
  78.                                   .createInstance(this.mnsIWebBrowserPersist);
  79.           // the default setting is to not decode. we need to decode.
  80.           webBrowserPersist.persistFlags = this.mnsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
  81.           webBrowserPersist.progressListener = this.viewSourceProgressListener;
  82.           webBrowserPersist.saveURI(uri, null, null, null, null, file);
  83.         } else {
  84.           // we'll use nsIWebPageDescriptor to get the source because it may not have to refetch
  85.           // the file from the server
  86.           var webShell = Components.classes["@mozilla.org/webshell;1"].createInstance();
  87.           this.viewSourceProgressListener.webShell = webShell;
  88.           var progress = webShell.QueryInterface(this.mnsIWebProgress);
  89.           progress.addProgressListener(this.viewSourceProgressListener,
  90.                                        this.mnsIWebProgress.NOTIFY_STATE_DOCUMENT);
  91.           var pageLoader = webShell.QueryInterface(this.mnsIWebPageDescriptor);    
  92.           pageLoader.loadPage(aPageDescriptor, this.mnsIWebPageDescriptor.DISPLAY_AS_SOURCE);
  93.         }
  94.       }
  95.     } catch (ex) {
  96.       // we failed loading it with the external editor.
  97.       Components.utils.reportError(ex);
  98.       this.handleCallBack(aCallBack, false, data);
  99.       return;
  100.     }
  101.   },
  102.  
  103.   // Default callback - opens the internal viewer if the external editor failed
  104.   internalViewerFallback: function(result, data)
  105.   {
  106.     if (!result) {
  107.       this.openInInternalViewer(data.url, data.pageDescriptor, data.doc);
  108.     }
  109.   },
  110.  
  111.   // Calls the callback, keeping in mind undefined or null values.
  112.   handleCallBack: function(aCallBack, result, data)
  113.   {
  114.     // ifcallback is undefined, default to the internal viewer
  115.     if (aCallBack === undefined) {
  116.       this.internalViewerFallback(result, data);
  117.     } else if (aCallBack) {
  118.       aCallBack(result, data);
  119.     }
  120.   },
  121.  
  122.   // Returns nsIProcess of the external view source editor or null
  123.   getExternalViewSourceEditor: function()
  124.   {
  125.     var editor = null;
  126.     var viewSourceAppPath = null;
  127.     try {
  128.       var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  129.                             .getService(Components.interfaces.nsIPrefBranch);
  130.       var prefPath = prefs.getCharPref("view_source.editor.path");
  131.       if (prefPath.length > 0) {
  132.         viewSourceAppPath = Components.classes["@mozilla.org/file/local;1"]
  133.                                       .createInstance(Components.interfaces.nsILocalFile);
  134.         viewSourceAppPath.initWithPath(prefPath);
  135.         // it's gotta be executable
  136.         if (viewSourceAppPath.exists() && viewSourceAppPath.isExecutable()) {
  137.           editor = Components.classes['@mozilla.org/process/util;1']
  138.                              .createInstance(Components.interfaces.nsIProcess);
  139.           editor.init(viewSourceAppPath);
  140.         }
  141.       }
  142.     }
  143.     catch (ex) {
  144.       Components.utils.reportError(ex);
  145.     }
  146.     return editor;
  147.   },
  148.  
  149.   viewSourceProgressListener: {
  150.  
  151.     mnsIWebProgressListener: Components.interfaces.nsIWebProgressListener,
  152.  
  153.     QueryInterface: function(aIID) {
  154.      if (aIID.equals(this.mnsIWebProgressListener) ||
  155.          aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  156.          aIID.equals(Components.interfaces.nsISupports))
  157.        return this;
  158.      throw Components.results.NS_NOINTERFACE;
  159.     },
  160.  
  161.     destroy: function() {
  162.         this.webShell = null;
  163.         this.editor = null;
  164.         this.callBack = null;
  165.         this.data = null;
  166.         this.file = null;
  167.     },
  168.  
  169.     onStateChange: function(aProgress, aRequest, aFlag, aStatus) {
  170.       // once it's done loading...
  171.       if ((aFlag & this.mnsIWebProgressListener.STATE_STOP) && aStatus == 0) {
  172.         try {
  173.           if (!this.file) {
  174.             // it's not saved to file yet, it's in the webshell
  175.  
  176.             // get a temporary filename using the attributes from the data object that
  177.             // openInExternalEditor gave us
  178.             this.file = gViewSourceUtils.getTemporaryFile(this.data.uri, this.data.doc, 
  179.                                                           this.data.doc.contentType);
  180.  
  181.             // we have to convert from the source charset.
  182.             var webNavigation = this.webShell.QueryInterface(Components.interfaces.nsIWebNavigation);
  183.             var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
  184.                                      .createInstance(Components.interfaces.nsIFileOutputStream);
  185.             foStream.init(this.file, 0x02 | 0x08 | 0x20, 0664, 0); // write | create | truncate
  186.             var coStream = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
  187.                                      .createInstance(Components.interfaces.nsIConverterOutputStream);
  188.             coStream.init(foStream, this.data.doc.characterSet, 0, null);
  189.  
  190.             // write the source to the file
  191.             coStream.writeString(webNavigation.document.body.textContent);
  192.           
  193.             // clean up
  194.             coStream.close();
  195.             foStream.close();
  196.           }
  197.           // fire up the editor
  198.           this.editor.run(false, [this.file.path], 1);
  199.  
  200.           gViewSourceUtils.handleCallBack(this.callBack, true, this.data);
  201.         } catch (ex) {
  202.           // we failed loading it with the external editor.
  203.           Components.utils.reportError(ex);
  204.           gViewSourceUtils.handleCallBack(this.callBack, false, this.data);
  205.         } finally {
  206.           this.destroy();
  207.         }
  208.       }
  209.       return 0;
  210.     },
  211.  
  212.     onLocationChange: function() {return 0;},
  213.     onProgressChange: function() {return 0;},
  214.     onStatusChange: function() {return 0;},
  215.     onSecurityChange: function() {return 0;},
  216.     onLinkIconAvailable: function() {return 0;},
  217.  
  218.     webShell: null,
  219.     editor: null,
  220.     callBack: null,
  221.     data: null,
  222.     file: null
  223.   },
  224.  
  225.   // returns an nsIFile for the passed document in the system temp directory
  226.   getTemporaryFile: function(aURI, aDocument, aContentType) {
  227.     var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
  228.                                 .getService(Components.interfaces.nsIProperties);
  229.     var tempFile = fileLocator.get("TmpD", Components.interfaces.nsIFile);
  230.     var fileName = getDefaultFileName(null, aURI, aDocument, aContentType);
  231.     var extension = getDefaultExtension(fileName, aURI, aContentType);
  232.     var leafName = getNormalizedLeafName(fileName, extension);
  233.     tempFile.append(leafName);
  234.     return tempFile;
  235.   }
  236. }
  237.